#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
凯利公式计算器exe打包脚本
功能说明：使用PyInstaller将启动器打包成exe文件
作者：luohe
创建时间：2024-12-19
修改时间：2024-12-19
"""

import os
import sys
import subprocess
import shutil
from pathlib import Path

def check_pyinstaller():
    """检查PyInstaller是否已安装"""
    try:
        import PyInstaller
        print("✓ PyInstaller 已安装")
        return True
    except ImportError:
        print("❌ PyInstaller 未安装，正在安装...")
        try:
            subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], check=True)
            print("✓ PyInstaller 安装成功")
            return True
        except subprocess.CalledProcessError:
            print("❌ PyInstaller 安装失败")
            return False

def create_spec_file():
    """创建PyInstaller spec文件"""
    spec_content = '''
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['launcher.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('streamlit_kelly_calculator.py', '.'),
        ('requirements.txt', '.'),
        ('README.md', '.'),
        ('QUICK_START.md', '.'),
    ],
    hiddenimports=[
        'streamlit',
        'plotly',
        'numpy',
        'pandas',
        'scipy',
        'matplotlib',
        'seaborn',
        'openpyxl',
        'xlsxwriter',
        'streamlit.web.cli',
        'streamlit.runtime.scriptrunner.script_runner',
        'plotly.graph_objects',
        'plotly.express',
        'plotly.subplots',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='凯利公式计算器',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon='calculator.ico'  # 如果有图标文件的话
)
'''
    
    with open('kelly_calculator.spec', 'w', encoding='utf-8') as f:
        f.write(spec_content)
    
    print("✓ 已创建 kelly_calculator.spec 文件")

def build_exe():
    """构建exe文件"""
    print("开始构建exe文件...")
    
    try:
        # 使用spec文件构建
        cmd = [sys.executable, "-m", "PyInstaller", "kelly_calculator.spec", "--clean"]
        
        print(f"执行命令: {' '.join(cmd)}")
        result = subprocess.run(cmd, check=True, capture_output=True, text=True)
        
        print("✓ exe文件构建成功！")
        print(f"输出目录: {os.path.abspath('dist')}")
        
        # 检查生成的文件
        exe_path = Path("dist/凯利公式计算器.exe")
        if exe_path.exists():
            print(f"✓ exe文件已生成: {exe_path.absolute()}")
            print(f"文件大小: {exe_path.stat().st_size / (1024*1024):.1f} MB")
        else:
            print("❌ exe文件未找到")
        
        return True
        
    except subprocess.CalledProcessError as e:
        print(f"❌ 构建失败: {e}")
        if e.stdout:
            print(f"标准输出: {e.stdout}")
        if e.stderr:
            print(f"错误输出: {e.stderr}")
        return False

def create_installer_script():
    """创建安装脚本"""
    installer_content = '''
@echo off
chcp 65001 > nul
echo ========================================
echo     凯利公式计算器 安装程序
echo ========================================
echo.

set "INSTALL_DIR=%USERPROFILE%\\Desktop\\凯利公式计算器"

echo 正在创建安装目录...
if not exist "%INSTALL_DIR%" mkdir "%INSTALL_DIR%"

echo 正在复制文件...
copy "凯利公式计算器.exe" "%INSTALL_DIR%\\"
copy "README.md" "%INSTALL_DIR%\\" 2>nul
copy "QUICK_START.md" "%INSTALL_DIR%\\" 2>nul

echo 正在创建桌面快捷方式...
powershell -Command "$WshShell = New-Object -comObject WScript.Shell; $Shortcut = $WshShell.CreateShortcut('%USERPROFILE%\\Desktop\\凯利公式计算器.lnk'); $Shortcut.TargetPath = '%INSTALL_DIR%\\凯利公式计算器.exe'; $Shortcut.WorkingDirectory = '%INSTALL_DIR%'; $Shortcut.Description = '专业的投资比例计算与风险分析工具'; $Shortcut.Save()"

echo.
echo ✓ 安装完成！
echo ✓ 程序已安装到: %INSTALL_DIR%
echo ✓ 桌面快捷方式已创建
echo.
echo 按任意键退出...
pause > nul
'''
    
    with open('install.bat', 'w', encoding='gbk') as f:
        f.write(installer_content)
    
    print("✓ 已创建 install.bat 安装脚本")

def create_readme_for_exe():
    """为exe版本创建说明文件"""
    readme_content = '''
# 凯利公式计算器 - 可执行版本

## 📋 版本信息
- 版本：v2.0 Portable
- 构建时间：2024-12-19
- 作者：luohe

## 🚀 快速开始

### 方法一：直接运行
1. 双击 `凯利公式计算器.exe` 启动程序
2. 在启动器界面点击"🚀 启动计算器"
3. 程序会自动打开浏览器访问计算器
4. 在Web界面输入交易参数进行分析

### 方法二：使用安装脚本
1. 运行 `install.bat` 安装到桌面
2. 使用桌面快捷方式启动程序

## 💡 使用说明

### 输入参数
- **胜率**：交易获胜的概率（0-1之间）
- **胜利收益率**：获胜时的收益率（大于0）
- **失败损失率**：失败时的损失率（0-1之间）

### 分析结果
- **凯利分数**：建议的投资比例
- **期望增长率**：预期的资金增长率
- **风险评级**：投资风险等级评估
- **可视化图表**：四种专业分析图表

## 🔧 功能特色

### 核心功能
- ✅ 精确的凯利公式计算
- ✅ 智能风险评级系统
- ✅ 四象限可视化分析
- ✅ 参数敏感性分析
- ✅ 蒙特卡洛模拟
- ✅ 分数凯利策略

### 技术特性
- ✅ 图形化启动器界面
- ✅ 自动依赖检查和安装
- ✅ Web界面交互式操作
- ✅ 实时参数调整
- ✅ 专业图表展示
- ✅ 便携式exe文件

## 📊 分析维度

1. **凯利分数计算**：基于胜率和盈亏比的最优投资比例
2. **增长曲线分析**：不同投资比例下的资金增长轨迹
3. **风险收益分析**：投资比例与风险收益的关系
4. **参数敏感性**：参数变化对结果的影响程度

## ⚠️ 注意事项

### 系统要求
- Windows 7/8/10/11
- 至少 100MB 可用磁盘空间
- 网络连接（首次运行安装依赖时）

### 使用建议
- 确保8501端口未被占用
- 建议使用Chrome或Edge浏览器
- 首次运行可能需要较长时间安装依赖
- 输入参数时请确保数值合理性

### 风险提示
- 本工具仅供参考，不构成投资建议
- 实际投资请结合市场情况和个人风险承受能力
- 过度杠杆可能导致重大损失

## 🛠️ 故障排除

### 常见问题
1. **启动失败**：检查是否有杀毒软件拦截
2. **端口占用**：关闭其他占用8501端口的程序
3. **浏览器无法打开**：手动访问 http://localhost:8501
4. **依赖安装失败**：检查网络连接，尝试重新启动

### 技术支持
- 作者：luohe
- 项目地址：[GitHub Repository]
- 问题反馈：[Issues]

## 📝 更新日志

### v2.0 (2024-12-19)
- ✅ 新增图形化启动器
- ✅ 支持exe打包分发
- ✅ 优化用户界面体验
- ✅ 增强错误处理机制
- ✅ 添加自动依赖管理

### v1.0 (2024-12-18)
- ✅ 基础凯利公式计算
- ✅ Streamlit Web界面
- ✅ 基础可视化功能

---

**感谢使用凯利公式计算器！**
'''
    
    with open('README_EXE.md', 'w', encoding='utf-8') as f:
        f.write(readme_content)
    
    print("✓ 已创建 README_EXE.md 说明文件")

def main():
    """主函数"""
    print("========================================")
    print("     凯利公式计算器 exe打包工具")
    print("========================================")
    print()
    
    # 检查当前目录
    required_files = ['launcher.py', 'streamlit_kelly_calculator.py']
    missing_files = [f for f in required_files if not os.path.exists(f)]
    
    if missing_files:
        print(f"❌ 缺少必要文件: {', '.join(missing_files)}")
        print("请确保在正确的项目目录中运行此脚本")
        return
    
    # 检查并安装PyInstaller
    if not check_pyinstaller():
        return
    
    # 创建配置文件
    create_spec_file()
    create_installer_script()
    create_readme_for_exe()
    
    print()
    print("准备开始构建...")
    input("按Enter键继续，或Ctrl+C取消")
    
    # 构建exe
    if build_exe():
        print()
        print("========================================")
        print("           构建完成！")
        print("========================================")
        print()
        print("生成的文件：")
        print("  📁 dist/凯利公式计算器.exe  - 主程序")
        print("  📄 install.bat              - 安装脚本")
        print("  📄 README_EXE.md           - 使用说明")
        print()
        print("使用方法：")
        print("  1. 直接运行 dist/凯利公式计算器.exe")
        print("  2. 或运行 install.bat 安装到桌面")
        print()
        print("注意：首次运行可能需要安装依赖包")
    else:
        print("❌ 构建失败，请检查错误信息")

if __name__ == "__main__":
    main()